package com.lock.utils.thread;

import com.google.common.util.concurrent.ThreadFactoryBuilder;

import java.util.concurrent.*;

/**
 * 线程池
 *
 * @author lcf
 */
public class ThreadPoolManager {
    /**
     * 内部静态类，保证线程安全
     */
    private static class ThreadPoolHolder {
        private static final ThreadPoolManager INSTANCE = new ThreadPoolManager();
    }

    /**
     * 线程池维护线程的最少数量
     */
    private static final int SIZE_CORE_POOL = 16;
    /**
     * 线程池维护线程的最大数量
     */
    private static final int SIZE_MAX_POOL = 128;
    /**
     * 线程池
     */
    private ThreadPoolExecutor poolExecutor;

    /**
     * 线程池单例创建方法
     */
    public static ThreadPoolManager newInstance() {
        return ThreadPoolHolder.INSTANCE;
    }

    /**
     * 将构造方法访问修饰符设为私有 禁止任意实例化
     */
    private ThreadPoolManager() {
        ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("global-thread-pool").build();
        poolExecutor = new ThreadPoolExecutor(SIZE_CORE_POOL, SIZE_MAX_POOL, 30 * 1000,
                TimeUnit.MILLISECONDS, new LinkedBlockingDeque<>(1024), threadFactory,
                new ThreadPoolExecutor.CallerRunsPolicy());
    }

    /**
     * 将线程池初始化，核心线程数量
     */
    public void prepare() {
        if (poolExecutor.isShutdown() && !poolExecutor.prestartCoreThread()) {
            poolExecutor.prestartAllCoreThreads();
        }
    }

    /**
     * 向线程池中添加任务方法
     */
    public void addExecuteTask(Runnable task) {
        if (task != null) {
            poolExecutor.execute(task);
        }
    }

    /**
     * 判断是否是最后一个任务
     */
    public boolean isTaskEnd() {
        return poolExecutor.getActiveCount() == 0;
    }

    /**
     * 获取缓存大小
     */
    public int getQueue() {
        return poolExecutor.getQueue().size();
    }

    /**
     * 获取线程池中的线程数目
     */
    public int getPoolSize() {
        return poolExecutor.getPoolSize();
    }

    /**
     * 获取已完成的任务数
     */
    public long getCompletedTaskCount() {
        return poolExecutor.getCompletedTaskCount();
    }

    @Override
    protected void finalize() throws Throwable {
        this.shutdown();
        super.finalize();
    }

    /**
     * 获取线程池
     */
    public static Executor getPoolExecutor() {
        return newInstance().poolExecutor;
    }

    /**
     * 关闭线程池，不在接受新的任务，会把已接受的任务执行完
     */
    private void shutdown() {
        poolExecutor.shutdown();
    }
}
